# app/views.py
import logging
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from django.shortcuts import get_object_or_404
from django.db.models import Q

from .models import ScheduledTask, TaskExecutionLog, TaskMetrics
from .serializers import (
    ScheduledTaskSerializer, ScheduledTaskCreateSerializer,
    TaskExecutionLogSerializer, TaskMetricsSerializer,
    AsyncTaskSubmitSerializer, TaskControlSerializer,
    SchedulerStatusSerializer, JobInfoSerializer
)
from utils.task_service import TaskService
from utils.scheduler_manager import SchedulerManager

logger = logging.getLogger(__name__)


class StandardResultPagination(PageNumberPagination):
    """标准分页器"""
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100


class ScheduledTaskViewSet(viewsets.ModelViewSet):
    """调度任务视图集"""
    
    queryset = ScheduledTask.objects.all().order_by('-created_at')
    pagination_class = StandardResultPagination
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.task_service = TaskService()
    
    def get_serializer_class(self):
        if self.action == 'create':
            return ScheduledTaskCreateSerializer
        return ScheduledTaskSerializer
    
    def list(self, request, *args, **kwargs):
        """获取任务列表"""
        queryset = self.filter_queryset(self.get_queryset())
        
        # 筛选参数
        is_active = request.query_params.get('is_active')
        trigger_type = request.query_params.get('trigger_type')
        search = request.query_params.get('search')
        
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')
        
        if trigger_type:
            queryset = queryset.filter(trigger_type=trigger_type)
        
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) | 
                Q(description__icontains=search) |
                Q(module_path__icontains=search) |
                Q(function_name__icontains=search)
            )
        
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
    
    def create(self, request, *args, **kwargs):
        """创建任务"""
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            try:
                # 使用任务服务创建任务
                task = self.task_service.create_scheduled_task(**serializer.validated_data)
                response_serializer = ScheduledTaskSerializer(task)
                
                return Response(
                    {
                        'success': True,
                        'message': '任务创建成功',
                        'data': response_serializer.data
                    },
                    status=status.HTTP_201_CREATED
                )
            except Exception as e:
                logger.error(f"创建任务失败: {e}")
                return Response(
                    {
                        'success': False,
                        'message': f'创建任务失败: {str(e)}'
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
        
        return Response(
            {
                'success': False,
                'message': '数据验证失败',
                'errors': serializer.errors
            },
            status=status.HTTP_400_BAD_REQUEST
        )
    
    def update(self, request, *args, **kwargs):
        """更新任务"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        
        if serializer.is_valid():
            try:
                # 使用任务服务更新任务
                updated_task = self.task_service.update_scheduled_task(
                    instance.id, **serializer.validated_data
                )
                
                if updated_task:
                    response_serializer = ScheduledTaskSerializer(updated_task)
                    return Response(
                        {
                            'success': True,
                            'message': '任务更新成功',
                            'data': response_serializer.data
                        }
                    )
                else:
                    return Response(
                        {
                            'success': False,
                            'message': '任务更新失败'
                        },
                        status=status.HTTP_400_BAD_REQUEST
                    )
            except Exception as e:
                logger.error(f"更新任务失败: {e}")
                return Response(
                    {
                        'success': False,
                        'message': f'更新任务失败: {str(e)}'
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
        
        return Response(
            {
                'success': False,
                'message': '数据验证失败',
                'errors': serializer.errors
            },
            status=status.HTTP_400_BAD_REQUEST
        )
    
    def destroy(self, request, *args, **kwargs):
        """删除任务"""
        instance = self.get_object()
        
        try:
            success = self.task_service.delete_scheduled_task(instance.id)
            
            if success:
                return Response(
                    {
                        'success': True,
                        'message': '任务删除成功'
                    },
                    status=status.HTTP_204_NO_CONTENT
                )
            else:
                return Response(
                    {
                        'success': False,
                        'message': '任务删除失败'
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
        except Exception as e:
            logger.error(f"删除任务失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'删除任务失败: {str(e)}'
                },
                status=status.HTTP_400_BAD_REQUEST
            )
    
    @action(detail=True, methods=['post'])
    def control(self, request, pk=None):
        """任务控制（暂停、恢复、立即运行）"""
        task = self.get_object()
        serializer = TaskControlSerializer(data=request.data)
        
        if not serializer.is_valid():
            return Response(
                {
                    'success': False,
                    'message': '参数验证失败',
                    'errors': serializer.errors
                },
                status=status.HTTP_400_BAD_REQUEST
            )
        
        action_type = serializer.validated_data['action']
        
        try:
            if action_type == 'pause':
                success = self.task_service.pause_task(task.id)
                message = '任务暂停成功' if success else '任务暂停失败'
            elif action_type == 'resume':
                success = self.task_service.resume_task(task.id)
                message = '任务恢复成功' if success else '任务恢复失败'
            elif action_type == 'run_now':
                success = self.task_service.run_task_now(task.id)
                message = '任务已设置为立即运行' if success else '立即运行任务失败'
            elif action_type == 'delete':
                success = self.task_service.delete_scheduled_task(task.id)
                message = '任务删除成功' if success else '任务删除失败'
            else:
                return Response(
                    {
                        'success': False,
                        'message': '不支持的操作'
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            return Response(
                {
                    'success': success,
                    'message': message
                },
                status=status.HTTP_200_OK if success else status.HTTP_400_BAD_REQUEST
            )
            
        except Exception as e:
            logger.error(f"任务控制失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'操作失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=True, methods=['get'])
    def logs(self, request, pk=None):
        """获取任务执行日志"""
        task = self.get_object()
        limit = int(request.query_params.get('limit', 50))
        
        logs = self.task_service.get_task_logs(task.id, limit)
        serializer = TaskExecutionLogSerializer(logs, many=True)
        
        return Response(
            {
                'success': True,
                'data': serializer.data,
                'count': len(logs)
            }
        )
    
    @action(detail=True, methods=['get'])
    def metrics(self, request, pk=None):
        """获取任务统计信息"""
        task = self.get_object()
        
        metrics = self.task_service.get_task_metrics(task.id)
        if metrics:
            serializer = TaskMetricsSerializer(metrics)
            return Response(
                {
                    'success': True,
                    'data': serializer.data
                }
            )
        else:
            return Response(
                {
                    'success': False,
                    'message': '无统计数据'
                },
                status=status.HTTP_404_NOT_FOUND
            )


class TaskExecutionLogViewSet(viewsets.ReadOnlyModelViewSet):
    """任务执行日志视图集"""
    
    queryset = TaskExecutionLog.objects.all().order_by('-start_time')
    serializer_class = TaskExecutionLogSerializer
    pagination_class = StandardResultPagination
    
    def list(self, request, *args, **kwargs):
        """获取执行日志列表"""
        queryset = self.filter_queryset(self.get_queryset())
        
        # 筛选参数
        status_filter = request.query_params.get('status')
        task_id = request.query_params.get('task_id')
        strategy_id = request.query_params.get('strategy_id')
        
        if status_filter:
            queryset = queryset.filter(status=status_filter)
        
        if task_id:
            queryset = queryset.filter(scheduled_task_id=task_id)
        
        if strategy_id:
            queryset = queryset.filter(strategy_id=strategy_id)
        
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)


class AsyncTaskViewSet(viewsets.ViewSet):
    """异步任务视图集"""
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.task_service = TaskService()
    
    @action(detail=False, methods=['post'])
    def submit(self, request):
        """提交异步任务"""
        serializer = AsyncTaskSubmitSerializer(data=request.data)
        
        if not serializer.is_valid():
            return Response(
                {
                    'success': False,
                    'message': '参数验证失败',
                    'errors': serializer.errors
                },
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            task_id = self.task_service.submit_async_task(**serializer.validated_data)
            
            if task_id:
                return Response(
                    {
                        'success': True,
                        'message': '异步任务提交成功',
                        'task_id': task_id
                    },
                    status=status.HTTP_201_CREATED
                )
            else:
                return Response(
                    {
                        'success': False,
                        'message': '异步任务提交失败'
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
        except Exception as e:
            logger.error(f"提交异步任务失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'提交异步任务失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=True, methods=['get'])
    def status(self, request, pk=None):
        """获取异步任务状态"""
        try:
            task_id = int(pk)
            task_status = self.task_service.get_async_task_status(task_id)
            
            return Response(
                {
                    'success': True,
                    'data': task_status
                }
            )
        except ValueError:
            return Response(
                {
                    'success': False,
                    'message': '无效的任务ID'
                },
                status=status.HTTP_400_BAD_REQUEST
            )
        except Exception as e:
            logger.error(f"获取异步任务状态失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'获取任务状态失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def list_all(self, request):
        """获取所有异步任务状态"""
        try:
            all_tasks = self.task_service.get_all_async_tasks()
            
            return Response(
                {
                    'success': True,
                    'data': all_tasks,
                    'count': len(all_tasks)
                }
            )
        except Exception as e:
            logger.error(f"获取所有异步任务失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'获取任务列表失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class SchedulerViewSet(viewsets.ViewSet):
    """调度器管理视图集"""
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.scheduler_manager = SchedulerManager()
    
    @action(detail=False, methods=['get'])
    def status(self, request):
        """获取调度器状态"""
        try:
            scheduler_status = self.scheduler_manager.get_scheduler_status()
            serializer = SchedulerStatusSerializer(scheduler_status)
            
            return Response(
                {
                    'success': True,
                    'data': serializer.data
                }
            )
        except Exception as e:
            logger.error(f"获取调度器状态失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'获取调度器状态失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def jobs(self, request):
        """获取调度器中的所有任务"""
        try:
            jobs = self.scheduler_manager.get_jobs()
            serializer = JobInfoSerializer(jobs, many=True)
            
            return Response(
                {
                    'success': True,
                    'data': serializer.data,
                    'count': len(jobs)
                }
            )
        except Exception as e:
            logger.error(f"获取调度器任务失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'获取调度器任务失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def start(self, request):
        """启动调度器"""
        try:
            if self.scheduler_manager.is_running:
                return Response(
                    {
                        'success': False,
                        'message': '调度器已经在运行'
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            self.scheduler_manager.start_scheduler()
            
            return Response(
                {
                    'success': True,
                    'message': '调度器启动成功'
                }
            )
        except Exception as e:
            logger.error(f"启动调度器失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'启动调度器失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def stop(self, request):
        """停止调度器"""
        try:
            if not self.scheduler_manager.is_running:
                return Response(
                    {
                        'success': False,
                        'message': '调度器未运行'
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            self.scheduler_manager.stop_scheduler()
            
            return Response(
                {
                    'success': True,
                    'message': '调度器停止成功'
                }
            )
        except Exception as e:
            logger.error(f"停止调度器失败: {e}")
            return Response(
                {
                    'success': False,
                    'message': f'停止调度器失败: {str(e)}'
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )